﻿package me.zhengjie.common.exception.handler

import me.zhengjie.common.exception.BadRequestException
import me.zhengjie.common.exception.EntityExistException
import me.zhengjie.common.exception.EntityNotFoundException
import me.zhengjie.common.utils.ThrowableUtil
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.security.access.AccessDeniedException
import org.springframework.security.authentication.BadCredentialsException
import org.springframework.validation.FieldError
import org.springframework.web.bind.MethodArgumentNotValidException
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.RestControllerAdvice
import java.util.*


/**
 * @author Kuki
 * @date 2024-11-10
 */
//@Slf4j
@RestControllerAdvice
class GlobalExceptionHandler {
    final var log = org.slf4j.LoggerFactory.getLogger(GlobalExceptionHandler::class.java)
    /**
     * 处理所有不可知的异常
     */
    @ExceptionHandler(Throwable::class)
    fun handleException(e: Throwable): ResponseEntity<ApiError?> {
        // 打印堆栈信息
        log.error(ThrowableUtil.getStackTrace(e))
        return buildResponseEntity(ApiError.error(e.message))
    }

    /**
     * 处理 接口无权访问异常AccessDeniedException
     */
    @ExceptionHandler(AccessDeniedException::class)
    fun handleAccessDeniedException(e: AccessDeniedException): ResponseEntity<*> {
        // 打印堆栈信息
        log.error(ThrowableUtil.getStackTrace(e))
        return buildResponseEntity(ApiError.error(HttpStatus.FORBIDDEN.value(), e.message))
    }

    /**
     * BadCredentialsException
     */
    @ExceptionHandler(BadCredentialsException::class)
    fun badCredentialsException(e: BadCredentialsException): ResponseEntity<ApiError?>? {
        // 打印堆栈信息
        val message = if ("坏的凭证" == e.message) "用户名或密码不正确" else e.message!!
        log.error(message)
        return buildResponseEntity(ApiError.error(message))
    }
    /**
     * 处理自定义异常
     */
    @ExceptionHandler(value = [BadRequestException::class])
    fun badRequestException(e: BadRequestException): ResponseEntity<ApiError?> {
        // 打印堆栈信息
        log.error(ThrowableUtil.getStackTrace(e))
        return buildResponseEntity(ApiError.error(e.status, e.message))
    }

    /**
     * 处理 EntityExist
     */
    @ExceptionHandler(value = [EntityExistException::class])
    fun entityExistException(e: EntityExistException): ResponseEntity<ApiError?> {
        // 打印堆栈信息
        log.error(ThrowableUtil.getStackTrace(e))
        return buildResponseEntity(ApiError.error(e.message))
    }

    /**
     * 处理 EntityNotFound
     */
    @ExceptionHandler(value = [EntityNotFoundException::class])
    fun entityNotFoundException(e: EntityNotFoundException): ResponseEntity<ApiError?> {
        // 打印堆栈信息
        log.error(ThrowableUtil.getStackTrace(e))
        return buildResponseEntity(ApiError.error(HttpStatus.NOT_FOUND.value(), e.message))
    }

    /**
     * 处理所有接口数据验证异常
     */
    @ExceptionHandler(MethodArgumentNotValidException::class)
    fun handleMethodArgumentNotValidException(e: MethodArgumentNotValidException): ResponseEntity<ApiError?> {
        // 打印堆栈信息

        // 打印堆栈信息
        log.error(ThrowableUtil.getStackTrace(e))
        val objectError = e.bindingResult.allErrors[0]
        var message = objectError.defaultMessage
        if (objectError is FieldError) {
            message = objectError.field + ": " + message
        }
        return buildResponseEntity(ApiError.error(message))
    }

    /**
     * 统一返回
     */
    private fun buildResponseEntity(apiError: ApiError): ResponseEntity<ApiError?> {
        return ResponseEntity<ApiError?>(apiError, HttpStatus.valueOf(apiError.status!!))
    }
}
